/************************************************************************************************
 *   深圳市摩西尔电子有限公司 @版本所有@
 *
 *   此文件用于str试算
 *
 * 修改:
 *   1. 类型 : 创建
 *      作者 : caobingxing
 *      时间 : 2019.10.23
 *      内容 : 所有代码
 *************************************************************************************************/

/* exported mc_try_calculate */
/* global mc_sdk_param */
/* global mc_sdk_module */
/* global $ */

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    str试算
 * 参数:
 *    @param {Promise<string>} register_info 显示芯片注册信息
 *    @param {Promise<object>} str_sdk_module 模组信息字串
 *    @param {Promise<object>} fun_calblack 回调函数(试算成功模组)
 *    @param {Promise<boolean>} b_if_get_access 判断是否获取注册信息
 * 返回：
 *    NA
 * 备注:
 *  错误返回解释:
 *  1:传入参数错误
 *  2:计算行最大长度错误
 *  3:直接访问显示芯片获取失败
 *  4:单行最大单元个数错误
 *  5:直接访问显示芯片获取错误
 *  6:直接访问显示芯片获取计算结果失败
 *  7:
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 徐烁超
 *      时间 : 2020.3.24
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_try_calculate(register_info, str_sdk_module, fun_calblack, b_if_get_access) {
    if ("function" !== typeof fun_calblack) {
        return;
    }
    if ("string" !== typeof register_info || 0 >= register_info.length) {
        fun_calblack(1);
        return;
    }
    if ("string" !== typeof str_sdk_module || 0 >= str_sdk_module.length) {
        fun_calblack(1);
        return;
    }
    var obj_sdk_module = new mc_sdk_module();

    obj_sdk_module.mc_util_mod_reset();
    obj_sdk_module.mc_util_mod_set_xml(str_sdk_module);

    var obj_calculate_data = {};
    var str_dispchip_name = obj_sdk_module.mc_util_mod_get_disp_chip();
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_json(register_info);

    // 单扫长度对齐
    obj_calculate_data.ui_scanalign = obj_sdk_param.get_attr_val(str_dispchip_name, "SCANALIGN");

    // scanalign获取失败则使用ic_channels数
    if ("string" !== typeof obj_calculate_data.ui_scanalign || 0 >= obj_calculate_data.ui_scanalign.length) {
        obj_calculate_data.ui_scanalign = obj_sdk_param.get_attr_val(str_dispchip_name, "IC_CHANNELS");
    }
    obj_calculate_data.ui_scanalign = Number(obj_calculate_data.ui_scanalign);

    // 单个str带载的灯珠数,如果不存在则不限制
    obj_calculate_data.max_str_led = Number(obj_sdk_param.get_attr_val(str_dispchip_name, "MAX_PIX_SIZE"));
    // 单个str最大带载的像素数,不存在则不使用
    obj_calculate_data.max_str_pix = Number(obj_sdk_param.get_attr_val(str_dispchip_name, "MAX_STR_SIZE"));
    // 所有STR灯珠总数的上限，不存在则不限制w
    obj_calculate_data.max_box_led = Number(obj_sdk_param.get_attr_val(str_dispchip_name, "MAX_BOX_LED"));
    // 所有STR像素的上限，不存在则不限制
    obj_calculate_data.max_box_pix = Number(obj_sdk_param.get_attr_val(str_dispchip_name, "MAX_BOX_PIX"));
    // 芯片支持的最大行扫数（此数据后面页面可能会修改，如果有修改则使用已经知的数据，否则从芯片属性中读取,若不存存，默认取64）
    obj_calculate_data.ui_max_scan_rows = Number(obj_sdk_param.get_attr_val(str_dispchip_name, "MAX_SCAN_ROWS"));
    // 获取失败则设置默认值为64
    if (isNaN(obj_calculate_data.ui_max_scan_rows)) {
        obj_calculate_data.ui_max_scan_rows = 64;
    }
    // 芯片通道数
    obj_calculate_data.ui_ic_channels = Number(obj_sdk_param.get_attr_val(str_dispchip_name, "IC_CHANNELS"));

    // 计算当前str数量
    obj_calculate_data.ui_str_cnt = obj_sdk_module.mc_util_mod_get_str_grp_mode();

    // 计算单条str最大灯珠数
    obj_calculate_data.str_max_len = mc_calculate_min_num([obj_calculate_data.max_str_led, (obj_calculate_data.max_str_pix * 3), parseInt((obj_calculate_data.max_box_led / obj_calculate_data.ui_str_cnt), 10), parseInt((obj_calculate_data.max_box_pix * 3 / obj_calculate_data.ui_str_cnt), 10)]);

    // 计算行单元长
    obj_calculate_data.ui_scan_cell_len = mc_calculate_min_common(obj_calculate_data.ui_scanalign, obj_calculate_data.ui_ic_channels);

    // 计算行最大长度
    if (!mc_calculate_scan_max_len()) {
        fun_calblack(2);
        return;
    }

    // 计算单行最大单元个数
    obj_calculate_data.ui_scan_cell_cnt = parseInt((obj_calculate_data.scan_max_len / obj_calculate_data.ui_scan_cell_len), 10);


    // 设置值
    obj_calculate_data.ui_disable_cell_cnt = obj_calculate_data.ui_scan_cell_cnt;
    obj_calculate_data.ui_enable_cell_cnt = 0;
    obj_calculate_data.ui_test_cell_cnt = obj_calculate_data.ui_disable_cell_cnt;
    obj_calculate_data.ui_tmp_cnt = 0;
    // 计算单行长度
    obj_calculate_data.ui_scan_len = obj_calculate_data.ui_test_cell_cnt * obj_calculate_data.ui_scan_cell_len;

    mc_calculate_construction_module(obj_sdk_module, obj_calculate_data, function (obj_sdk_module_req) {
        if ("number" === typeof obj_sdk_module_req) {
            fun_calblack(obj_sdk_module_req);
            return;
        }
        fun_calblack(obj_sdk_module_req);
        return;
    }, b_if_get_access);

    // 计算行最大长度
    function mc_calculate_scan_max_len() {
        obj_calculate_data.scan_max_len = parseInt((obj_calculate_data.str_max_len / obj_calculate_data.ui_max_scan_rows), 10);

        if (obj_calculate_data.scan_max_len >= obj_calculate_data.ui_scan_cell_len) {
            return true;
        }
        for (var idx_row = obj_calculate_data.ui_max_scan_rows; 0 < obj_calculate_data.ui_max_scan_rows; idx_row--) {
            obj_calculate_data.ui_max_scan_rows--;
            obj_calculate_data.scan_max_len = parseInt((obj_calculate_data.str_max_len / obj_calculate_data.ui_max_scan_rows), 10);
            if (obj_calculate_data.scan_max_len >= obj_calculate_data.ui_scan_cell_len) {
                break;
            }
        }
        if (obj_calculate_data.scan_max_len >= obj_calculate_data.ui_scan_cell_len) {
            return true;
        }
        return false;
    }
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    求三个数值的最小公倍数
 * 参数:
 *    @param {Promise<number>}num1 计算值
 *    @param {Promise<number>}num2 计算值
 *    @param {Promise<number>}num3 计算值
 * 返回：
 *    @returns {Promise<number>} 最小公倍数
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 徐烁超
 *      时间 : 2020.3.24
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_calculate_min_common(num1, num2, num3) {
    if ("number" !== typeof num1 || 0 >= num1 || isNaN(num1)) {
        num1 = 1;
    }
    if ("number" !== typeof num2 || 0 >= num2 || isNaN(num2)) {
        num2 = 1;
    }
    if ("number" !== typeof num3 || 0 >= num3 || isNaN(num3)) {
        num3 = 1;
    }
    var max = num1;
    var min = num1;
    var lcm = -1;

    if (num2 > num1) {
        max = num2;
    }
    if (max < num3) {
        max = num3;
    }
    if (num2 < num1) {
        min = num2;
    }
    if (num3 < min) {
        min = num3;
    }
    for (var idx_num = max; idx_num <= num1 * num2 * num3; idx_num++) {
        if (0 === idx_num % num1 && 0 === idx_num % num2 && 0 === idx_num % num3) {
            lcm = idx_num;
            break;
        }
    }
    return lcm;
}


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    求最小值
 * 参数:
 *    @param {Promise<Array>} ary_num 计算值数组
 * 返回：
 *    @returns {Promise<number>} 最小值
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 徐烁超
 *      时间 : 2020.3.24
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_calculate_min_num(ary_num) {
    if (!Array.isArray(ary_num) || 0 >= ary_num.length) {
        return false;
    }
    var ui_min_num = 0xFFFFFFFF;

    for (var idx_num = 0; idx_num < ary_num.length; idx_num++) {
        var ui_num = ary_num[idx_num];

        if ("number" === typeof ui_num && !isNaN(ui_num)) {
            if (ui_min_num > ui_num) {
                ui_min_num = ui_num;
            }
        }
    }

    return ui_min_num;
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    构造测试试算模组
 * 参数:
 *    @param {Promise<Object>}obj_sdk_module 页面模组信息
 *    @param {Promise<Object>}obj_calculate_data 试算数据对象
 *    @param {Promise<Function>}fun_callback   回调函数
 *    @param {Promise<boolean>}b_if_get_access 是否获取注册信息
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 徐烁超
 *      时间 : 2020.3.24
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_calculate_construction_module(obj_sdk_module, obj_calculate_data, fun_callback, b_if_get_access) {
    //显示芯片名称
    var str_displaychip_name = obj_sdk_module.mc_util_mod_get_disp_chip();
    //str条数
    var ui_str_cnt = obj_sdk_module.mc_util_mod_get_str_cnt();
    //行扫数
    var ui_scan_cnt = obj_calculate_data.ui_max_scan_rows;
    //单行长度
    var ui_can_len = obj_calculate_data.ui_scan_len;

    ui_len_single = ui_can_len;

    for (var idx_pix_str = 0; idx_pix_str < ui_str_cnt; idx_pix_str++) {
        obj_sdk_module.mc_util_mod_reset_str_pix(idx_pix_str);
        obj_sdk_module.mc_util_mod_set_str_name(idx_pix_str, "STR_" + idx_pix_str);
        obj_sdk_module.mc_util_mod_set_str_pin(idx_pix_str, "STR_" + idx_pix_str);
        for (var idx_str_x = 0; idx_str_x < ui_scan_cnt; idx_str_x++) {
            for (var idx_str_y = 0; idx_str_y < ui_can_len; idx_str_y++) {
                obj_sdk_module.mc_util_mod_set_pix_info(idx_pix_str, idx_str_x, idx_str_y, 0, 0, "R");
            }
        }
    }
    // console.log(obj_sdk_module.mc_util_mod_get_xml());

    //测试试算模组
    mc_calculate_access_set_mod_file(obj_sdk_module.mc_util_mod_get_xml(), function () {
        if (!b_if_get_access) {
            fun_callback();
            return;
        }
        mc_calculate_get_display_chip(str_displaychip_name, function (str_display_data) {
            if ("string" !== typeof str_display_data || 0 >= str_display_data.length) {
                fun_callback(3);
                return;
            }
            if (0 >= obj_calculate_data.ui_scan_cell_cnt) {
                fun_callback(4);
                return;
            }
            var obj_sdk_param = new mc_sdk_param();

            obj_sdk_param.set_param_clear();
            obj_sdk_param.set_json(str_display_data);
            var error_code = obj_sdk_param.get_param_value("ERROR_CODE");

            if ("0x00000000" !== error_code && error_code) {
                fun_callback(5);
                return;
            }
            var str_disp_normal_xml = obj_sdk_param.get_param_value(str_displaychip_name);

            obj_sdk_param.set_param_clear();
            obj_sdk_param.set_json(str_disp_normal_xml);
            error_code = obj_sdk_param.get_param_value("ERROR_CODE");
            // console.log(error_code);
            if (!error_code) {
                fun_callback(6);
                return;
            }
            // 超载
            if ("1" === error_code || "2" === error_code || "3" === error_code) {
                obj_calculate_data.ui_disable_cell_cnt = obj_calculate_data.ui_test_cell_cnt;
                obj_calculate_data.ui_test_cell_cnt = Math.floor((obj_calculate_data.ui_disable_cell_cnt + obj_calculate_data.ui_enable_cell_cnt) / 2);


                if (0 < obj_calculate_data.ui_test_cell_cnt) {
                    obj_calculate_data.ui_scan_len = obj_calculate_data.ui_test_cell_cnt * obj_calculate_data.ui_scan_cell_len;
                    mc_calculate_construction_module(obj_sdk_module, obj_calculate_data, fun_callback, b_if_get_access);
                    return;
                }
                fun_callback(Number(error_code) + 7);
                return;
            }

            if ((obj_calculate_data.ui_test_cell_cnt + 1) >= obj_calculate_data.ui_disable_cell_cnt) {
                fun_callback(obj_sdk_module);
                return;
            }
            obj_calculate_data.ui_enable_cell_cnt = obj_calculate_data.ui_test_cell_cnt;
            obj_calculate_data.ui_test_cell_cnt = Math.floor((obj_calculate_data.ui_disable_cell_cnt + obj_calculate_data.ui_enable_cell_cnt) / 2);

            if (0 < obj_calculate_data.ui_test_cell_cnt) {
                obj_calculate_data.ui_scan_len = obj_calculate_data.ui_test_cell_cnt * obj_calculate_data.ui_scan_cell_len;
                mc_calculate_construction_module(obj_sdk_module, obj_calculate_data, fun_callback, b_if_get_access);
                return;
            }
            fun_callback(7);
            return;
        });
    });
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    设置模组信息
 * 参数:
 *    @param {Promise<object>}str_module_xml_txt 页面模组信息
 *    @param {Promise<Function>}fun_callback 回调函数
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 徐烁超
 *      时间 : 2020.3.24
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_calculate_access_set_mod_file(str_module_xml_txt, fun_callback) {
    if ("function" !== typeof fun_callback) {
        return;
    }
    if ("string" !== typeof str_module_xml_txt || 0 >= str_module_xml_txt.length) {
        fun_callback();
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_func("MOD_FILE");
    obj_sdk_param.set_cmd("SET_PARAM");
    obj_sdk_param.set_param_value("str_mod_text", str_module_xml_txt);
    obj_sdk_param.set_attr_val("str_mod_text", "FILE_OPT", "SET");
    $.post("/access_shell", obj_sdk_param.get_json(), function (_response, status) {
        if ("success" !== status) {
            return;
        }
        fun_callback();
    }, "text");
}

/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    直接访问显示芯片
 * 参数:
 *    @param {Promise<string>}str_dispchip_name 显示芯片名称
 *    @param {Promise<Function>}fun_callback 回调函数
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 徐烁超
 *      时间 : 2020.3.24
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_calculate_get_display_chip(str_dispchip_name, fun_callback) {
    if ("function" !== typeof fun_callback) {
        return;
    }
    if ("string" !== typeof str_dispchip_name || 0 >= str_dispchip_name.length) {
        fun_callback();
        return;
    }
    var obj_sdk_param = new mc_sdk_param();

    obj_sdk_param.set_param_clear();
    obj_sdk_param.set_func("DISPCHIP_ACCESS");
    obj_sdk_param.set_cmd("GET_PARAM");
    obj_sdk_param.set_param_value(str_dispchip_name, "");
    obj_sdk_param.set_attr_val(str_dispchip_name, "BOX_FILE", "mc_test_box");
    $.post("/access_shell", obj_sdk_param.get_json(), function (req, status) {
        if ("success" !== status) {
            fun_callback("");
            return;
        }
        fun_callback(req);
        return;
    });
}
